package com.erf.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 注入示意
 *  MapperScan扫描指定package下的mapper接口
 *  sqlSessionTemplateRef SqlSessionTemplate对象
 * @description DateSourceConfig2
 * @author zhangzy
 * @date 2022/5/15 17:56
 */
@Configuration
@MapperScan(basePackages = {"com.erf.mapper.ds2"},
        sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class DateSourceConfig2 {

    /**
     * 读取yml中的配置自动生成了ds2，注入
     */
    @Autowired
    @Qualifier("ds2")
    private DataSource ds2;

    /**
     * SqlSessionFactory是MyBatis的关键对象，它是单个数据库映射关系经过编译后的内存镜像。
     * SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来获得，
     * 而SqlSessionFactoryBuilder则可以从
     * XML配置文件或一个预先定制的Configuration的实例构建出SqlSessionFactory的实例。
     */
    @Bean(name = "test2SqlSessionFactory")
    @Primary
    public SqlSessionFactory test2SqlSessionFactory() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(ds2);
        // 注释的这三行是配置读取映射文件的场景的，这里没有使用映射文件，而是注解，所以注释了
        //ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        //Resource[] resources = resourcePatternResolver.getResources("classpath:mapping/*/*.xml");
        //factoryBean.setMapperLocations(resources);
        return factoryBean.getObject();
    }

    /**
     * 事务管理器
     */
    @Bean(name = "test2TransactionManager")
    @Primary
    public DataSourceTransactionManager test2TransactionManager() {
        return new DataSourceTransactionManager(ds2);
    }

    /**
     *
     * @param sqlSessionFactory  @Qualifier 说明一下这个注解，用在有多个一样的对象的情况下，
     *      spring不知道将哪一个对象注入给定的引用时，用这个注解指定注入哪一个对象。
     *      比如此时，因为多数据源配置，会有2个sqlSessionFactory
     *      名字定为test1SqlSessionFactory和test2SqlSessionFactory，
     *      这里是数据源2的配置，所以我指定要注入test1SqlSessionFactory
     * @return SqlSessionTemplate mybatis-spring 的代替SqlSessionFactory高级类
     */
    @Bean(name = "test2SqlSessionTemplate")
    @Primary
    public SqlSessionTemplate test1SqlSessionTemplate(
            @Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
